﻿using XLua;

namespace XLua_Ki
{
    [CSharpCallLua]
    public interface ILuaPathFunc { }                                 //自定义接口(空接口)

    [CSharpCallLua]
    public delegate ILuaPathFunc LuaPathAction(params object[] args); //获取Lua的无返回值的方法

    [CSharpCallLua]
    public delegate object LuaPathFunc(params object[] args);         //获取Lua的单个返回值的方法

    /// C#与Lua交互的工具类.
    public class LuaUtil
    {
        #region
        /* INTRODUCTION: table[index] 已过时的警告
         * var test = luaenv.Global.GetInPath<LuaTable>("test.list");      //获取Lua的多个返回值的table
         * Debug.Log(test.Get<T>("key"));                                  //再从table里获取对应"key"的<T>类型
         */
        #endregion

        /// <summary>
        /// 调用全局LuaFunction.返回Object的数组
        /// </summary>
        /// <param name="luaenv">lua虚拟机</param>
        /// <param name="functionName">lua方法全称.如"xxx"</param>
        /// <param name="args">需要的参数</param>
        public static object[] CallLuaGlobalMethod(LuaEnv luaenv, string functionName, params object[] args)
        {
            var func = luaenv.Global.Get<LuaFunction>(functionName.Trim());
            object[] ret = func.Call(args);
            return ret;
        }

        /// <summary>
        /// 调用全局LuaFunction.返回<T>的数组
        /// </summary>
        public static T[] CallLuaGlobalMethod<T>(LuaEnv luaenv, string functionName, params object[] args)
        {
            var func = luaenv.Global.Get<LuaFunction>(functionName.Trim());

            object[] temp = func.Call(args);
            T[] ret = new T[temp.Length];
            for (int i = 0; i < temp.Length; i++)
            {
                ret[i] = (T)(temp[i]);
            }
            return ret;
        }


        /// <summary>
        /// 调用类型Lua函数.无返回值
        /// </summary>
        /// <param name="functionName">方法名字.如"XXX.xxx"</param>
        public static void CallLuaPathAction(LuaEnv luaenv, string functionName, params object[] args)
        {
            var func = luaenv.Global.GetInPath<LuaPathAction>(functionName);
            func(args);
        }

        /// <summary>
        /// 调用类型Lua函数.返回一个object.
        /// </summary>
        public static object CallLuaPathFunc(LuaEnv luaenv, string functionName, params object[] args)
        {
            var func = luaenv.Global.GetInPath<LuaPathFunc>(functionName);
            return func(args);
        }

        /// <summary>
        /// 调用类型Lua函数.返回T类型.
        /// </summary>
        public static T CallLuaPathFunc<T>(LuaEnv luaenv, string functionName, params object[] args)
        {
            var func = luaenv.Global.GetInPath<LuaPathFunc>(functionName);
            return (T)func(args);
        }

        /// <summary>
        /// 获取类型Lua的table列表的其中一个Key值
        /// </summary>
        /// <typeparam name="T">key对应value的类型</typeparam>
        /// <param name="tableName">Table的名字.如"TestLua.list, TestLua是lua脚本名,list是table类型成员</param>
        /// <param name="key">Table列表里的一个Key</param>
        public static string GetLuaPathTable<T>(LuaEnv luaenv, string tableName, string key)
        {
            var table = luaenv.Global.GetInPath<LuaTable>(tableName);
            string ret = table.Get<T>(key).ToString();
            return ret;
        }

        /// 初始化AB
        public static void OnInitAB(string prefabName, UnityEngine.GameObject obj)
        {
            var ctrlName = CallLuaPathFunc(GameManager_Ki.Instance.LuaEnv, "PanelRegister.OnInit", prefabName) as string;
            //UnityEngine.Debug.Log(ctrlName + " oninit");
            CallLuaPathAction(GameManager_Ki.Instance.LuaEnv, ctrlName + ".Awake", obj);
        }

        /// <summary>
        /// 调用类型LuaClass函数.返回Object类型.
        /// functionName:传入如 "MyClass:New"或者"MyClass.New"都可以.
        /// </summary>
        public static object CallLuaTableFunc(LuaEnv luaenv, string functionName, params object[] args)
        {
            string[] tab_name = functionName.Contains(":") ? functionName.Split(':') : functionName.Split('.');
            LuaTable self = luaenv.Global.GetInPath<LuaTable>(tab_name[0]);
            var func = self.GetInPath<LuaPathFunc>(tab_name[1].Trim());

            object[] new_args = new object[args.Length + 1];
            new_args[0] = self;

            for (int i = 1; i < new_args.Length; i++)
            {
                new_args[i] = args[i - 1];
            }

            return func(new_args);
        }

        /// <summary>
        /// 调用类型LuaClass函数.返回T类型.
        /// </summary>
        public static T CallLuaTableFunc<T>(LuaEnv luaenv, string functionName, params object[] args)
        {
            string[] tab_name = functionName.Contains(":") ? functionName.Split(':') : functionName.Split('.');
            LuaTable self = luaenv.Global.GetInPath<LuaTable>(tab_name[0]);
            var func = self.GetInPath<LuaPathFunc>(tab_name[1].Trim());

            object[] new_args = new object[args.Length + 1];
            new_args[0] = self;

            for (int i = 1; i < new_args.Length; i++)
            {
                new_args[i] = args[i - 1];
            }

            return (T)func(new_args);
        }


        /// <summary>
        /// 调用类型LuaClass函数.无返回值.
        /// </summary>
        public static void CallLuaTableAction(LuaTable lua_table, string functionName, params object[] args)
        {
            string[] tab_name = functionName.Contains(":") ?
                functionName.Split(':') :
                functionName.Contains(".") ?
                functionName.Split('.')
                : new string[2]{
                null,functionName};

            var func = lua_table.GetInPath<LuaPathFunc>(tab_name[1].Trim());
            object[] new_args = new object[args.Length + 1];

            new_args[0] = lua_table;
            for (int i = 1; i < new_args.Length; i++)
            {
                new_args[i] = args[i - 1];
            }

            func(new_args);
        }


        /// 获取PanelManager对象
        public static PanelManager_Ki GetPanelManager()
        {
            return GameManager_Ki.Instance.GetPanelManager_Ki();
        }

        /// 获取AudioManager对象
        public static AudioManager_Ki GetAudioManager()
        {
            return GameManager_Ki.Instance.GetAudioManager_Ki();
        }

        /// 获取ObjectManager对象
        public static ObjectManager_Ki GetObjectManager()
        {
            return GameManager_Ki.Instance.GetObjectManager_Ki();
        }

        /// 获取ResourcesManager对象
        public static ResourcesManager_Ki GetResourcesManager()
        {
            return GameManager_Ki.Instance.GetResourcesManager_Ki();
        }

    }
}
